package com.iot08.admin.service;

import com.iot08.common.entity.admin.SysMenu;
import com.iot08.common.response.Response;
import com.iot08.common.service.base.BaseAdminService;
import com.iot08.common.utils.UUIDGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @version 1.0
 * @author: Rock
 * @Description: 菜单业务处理
 * @time: 2020/8/11 18:11
 */
@Slf4j
@Service
public class MenuService extends BaseAdminService<SysMenu> {

    @Resource
    private RoleService roleService;

    /**
     * @Description: 系统可用菜单列表
     * @author: Rock
     * @time: 2020/8/12 15:54
     * @version 1.0
     */
    public List<SysMenu> listAll() {
        List<SysMenu> result = new ArrayList<>();
        List<SysMenu> menus = mongoTemplate.find(new Query(Criteria.where("deleted").is(0)).with(Sort.by(Sort.Order.asc("order_num"))), SysMenu.class);
        handleMenu(result, menus);
        return result;
    }

    /**
     * @param [result, menus]
     * @Description: 处理菜单的层级关系
     * @time: 2020/8/21 14:50
     * @author: Rock
     * @version 1.0
     */
    private void handleMenu(List<SysMenu> result, List<SysMenu> menus) {
        Map<String, SysMenu> map = new HashMap<>();
        for (SysMenu menu : menus) {
            if (menu == null) {
                continue;
            }
            if (StringUtils.isEmpty(menu.getPid())) {
                result.add(menu);
            }
            menu.setSubMenu(new ArrayList<>());
            map.put(menu.getId(), menu);
        }

        for (SysMenu menu : menus) {
            if (menu == null || StringUtils.isEmpty(menu.getPid())) {
                continue;
            }
            SysMenu pmenu = map.get(menu.getPid());
            if (pmenu != null) {
                pmenu.getSubMenu().add(menu);
            }
        }
    }

    /**
     * @Description: 获取顶级菜单列表
     * @author: Rock
     * @time: 2020/8/12 18:57
     * @version 1.0
     */
    public List<SysMenu> listTopMenu() {
        return mongoTemplate.find(new Query(Criteria.where("deleted").is(0).and("pid").is("")),
                SysMenu.class);
    }

    /**
     * @Description: 获取父id获取菜单
     * @author: Rock
     * @time: 2020/8/12 19:01
     * @version 1.0
     */
    public List<SysMenu> listByPid(String pid) {
        return mongoTemplate.find(new Query(Criteria.where("deleted").is(0).and("pid").is(pid)),
                SysMenu.class);
    }

    /**
     * @Description: 获取非按钮的菜单
     * @author: Rock
     * @time: 2020/8/13 11:43
     * @version 1.0
     */
    public List<SysMenu> listNotBut() {
        return mongoTemplate.find(new Query(Criteria.where("deleted").is(0).and("type").lte(2)), SysMenu.class);
    }

    /**
     * @Description: 保存
     * @author: Rock
     * @time: 2020/8/13 12:08
     * @version 1.0
     */
    @Override
    public SysMenu save(SysMenu menu) {
        if (menu != null) {
            menu.setId(UUIDGenerator.generate());
            menu.setDeleted((short) 0);
            menu.setCreateDate(new Date());
            return mongoTemplate.save(menu);
        }
        return null;
    }

    /**
     * @Description:
     * @author: Rock
     * @time: 2020/8/13 12:09
     * @version 1.0
     */
    public SysMenu getById(String id) {
        return mongoTemplate.findOne(new Query(Criteria.where("id").is(id)), SysMenu.class);
    }

    /**
     * @Description: 更新菜单
     * @author: Rock
     * @time: 2020/8/13 14:39
     * @version 1.0
     */
    public void update(SysMenu menu) {
        if (menu != null) {
            Query query = new Query(Criteria.where("id").is(menu.getId()));
            if (query != null) {
                Update update = new Update();
                update.set("name", menu.getName());
                update.set("url", menu.getUrl());
                update.set("order_num", menu.getOrderNum());
                update.set("update_time", new Date());
                mongoTemplate.updateFirst(query, update, SysMenu.class);
            }
        }
    }

    /**
     * @Description: 更新删除状态
     * @author: Rock
     * @time: 2020/8/13 18:13
     * @version 1.0
     */
    public Response<Object> updateDeleted(String id) {
        if (roleService.countByMenuId(id) > 0) {
            return Response.failedResponse("存在角色引用该菜单，无法删除");
        }
        Query query = new Query(Criteria.where("id").is(id));
        if (query != null) {
            Update update = new Update();
            update.set("deleted", 1);
            update.set("update_time", new Date());
            mongoTemplate.updateFirst(query, update, SysMenu.class);
        }
        return Response.successResponse();
    }

    /**
     * @param [ids]
     * @Description: 根据id列表查询
     * @time: 2020/8/21 14:53
     * @author: Rock
     * @version 1.0
     */
    public List<SysMenu> listByIds(List<String> ids) {
        List<SysMenu> result = new ArrayList<>();
        List<SysMenu> menus = mongoTemplate.find(new Query(Criteria.where("_id").in(ids)).with(Sort.by(Sort.Order.asc("order_num"))), SysMenu.class);
        handleMenu(result, menus);
        return result;
    }

    /**
     * @param [ids]
     * @Description: 根据id列表获取按钮菜单
     * @time: 2020/8/21 17:44
     * @author: Rock
     * @version 1.0
     */
    public Map<String, Set<String>> handleBut(List<String> ids) {
        Map<String, Set<String>> result = new HashMap<>();
        List<SysMenu> butMenus = mongoTemplate.find(new Query(Criteria.where("_id").in(ids).and("type").is(3)), SysMenu.class);
        for (SysMenu menu : butMenus) {
            if (menu == null) {
                continue;
            }
            Set<String> set = result.get(menu.getPid());
            if (set == null) {
                set = new HashSet<>();
                set.add(menu.getUrl());
                result.put(menu.getPid(), set);
            } else {
                set.add(menu.getUrl());
            }
        }
        return result;
    }

    /**
     * @param [String]
     * @time: 2020/9/14 18:13
     * @author: Rock
     * @version 1.0
     */
    public SysMenu getByName(String name) {
        SysMenu menu = mongoTemplate.findOne(new Query(Criteria.where("name").is(name).and("deleted").is(0)), SysMenu.class);
        if (menu != null && StringUtils.isNotEmpty(menu.getPid())) {
            menu.setPmenu(getById(menu.getPid()));
        }
        return menu;
    }

}
